#include "window_common.h"
#include "gkt_door.h"

#if defined(GKT_CONFIG_DOOR_LOCK_AUTOMATIC) && GKT_CONFIG_DOOR_LOCK_AUTOMATIC

enum {
	WIDGET_ID_LIST = 0,
	WIDGET_ID_MAX
};

enum {
	TIMER_ID_TIMEOUT = 0,
	TIMER_ID_MAX
};

static const gkt_widget_list_item_s sc_window_motor_torsion_widget_list_items[] = {
	GKT_WIDGET_LIST_STATIC_ITEM(WINDOW_VOICE_COMBINED_ID(set_1), 
		GKT_DOOR_LOCK_MOTOR_TORSION_GEAR_LOW),
	GKT_WIDGET_LIST_STATIC_ITEM(WINDOW_VOICE_COMBINED_ID(set_2), 
		GKT_DOOR_LOCK_MOTOR_TORSION_GEAR_MEDIUM),
	GKT_WIDGET_LIST_STATIC_ITEM(WINDOW_VOICE_COMBINED_ID(set_3), 
		GKT_DOOR_LOCK_MOTOR_TORSION_GEAR_HIGH),
};

#define WINDOW_MOTOR_TORSION_LIST_ITEM_NUMS	\
	sizeof(sc_window_motor_torsion_widget_list_items) / sizeof(gkt_widget_list_item_s)

static const gkt_widget_list_attr_s sc_window_motor_torsion_list_attr = 
	GKT_WIDGET_LIST_STATIC_ATTR(WINDOW_MOTOR_TORSION_LIST_ITEM_NUMS, 
		sc_window_motor_torsion_widget_list_items);

GKT_WINDOW_WIDGET_DESCS_DEFINE(motor_torsion) = {
	[WIDGET_ID_LIST] = GKT_WIDGET_LIST_DESC(0, &sc_window_motor_torsion_list_attr),
};

struct _motor_torsion {
#if (GKT_MODULE_LOC_BACKBOARD == GKT_DOOR_LOCK_LOCATION)
	int	update_setting;
#endif
	gkt_door_lock_motor_torsion_gear_e	gear;
	uint32_t play_over;
};
static struct _motor_torsion s_motor_torsion;

#if (GKT_MODULE_LOC_BACKBOARD == GKT_DOOR_LOCK_LOCATION)
#define window_motor_torsion_clear_cfg_updating()	\
	do { s_motor_torsion.update_setting = 0; } while (0)
#else
#define window_motor_torsion_clear_cfg_updating()	do {} while (0)
#endif

static void window_motor_torsion_complete(window_result_e result)
{
	uint32_t voice_flags = GKT_WINDOW_VOICE_F_NOTIFY_END | GKT_WINDOW_VOICE_F_NOTIFY_ERROR;

	window_motor_torsion_clear_cfg_updating();

	if (WINDOW_RESULT_SET_SUCCESS == result) {
		gp_window_unreset_data->lock_motor_torsion_gear 
				= s_motor_torsion.gear;
#if (GKT_MODULE_LOC_FRONTBOARD == GKT_DOOR_LOCK_LOCATION)
		gkt_door_lock_get_motor_locked_rotor_voltage(
			gp_window_unreset_data->lock_motor_locked_rotor_voltage);
#endif
		window_data_save();
		gkt_window_voice_play(NULL, WINDOW_VOICE_COMBINED_ID(set_success), voice_flags, NULL);
	}
	else
		gkt_window_voice_play(NULL, WINDOW_VOICE_COMBINED_ID(set_failed), voice_flags, NULL);

	s_motor_torsion.play_over = 1;
}

static void window_motor_torsion_config(void)
{
	int retval;

	retval = gkt_door_lock_set_motor_torsion(s_motor_torsion.gear);
	if (GKT_SUCCESS == retval)
		window_motor_torsion_complete(WINDOW_RESULT_SET_SUCCESS);
#if (GKT_MODULE_LOC_BACKBOARD == GKT_DOOR_LOCK_LOCATION)
	else if (GKT_EINPROCESS == retval) {
		s_motor_torsion.update_setting = 1;
		gkt_window_timer_set(TIMER_ID_TIMEOUT, 2000, 0, 0);
	}
#endif
	else
		window_motor_torsion_complete(WINDOW_RESULT_SET_FAILED);
}

static int window_motor_torsion_event_handler(
				uint32_t major_type, uint32_t minor_type, 
				uint32_t id, uint32_t data)
{
	int retval = GKT_EVENT_HANDLE_CONTINUE;

	switch(major_type) {
		case GKT_EVENT_WINDOW:
			if (GKT_WINDOW_ACTIVE == minor_type) {
				window_motor_torsion_clear_cfg_updating();
				s_motor_torsion.gear = GKT_DOOR_LOCK_MOTOR_TORSION_GEAR_LOW;
				s_motor_torsion.play_over = 0;
				window_common_mask_except_number_repeat_return(WINDOW_MOTOR_TORSION_LIST_ITEM_NUMS);
			}
			break;
		case GKT_EVENT_WIDGET:
			if (GKT_WIDGET_EVENT_CLICK == minor_type) {
				s_motor_torsion.gear = sc_window_motor_torsion_widget_list_items[data].data;
				window_motor_torsion_config();
				retval = GKT_EVENT_HANDLE_COMPLETE;
			}
			break;
#if (GKT_MODULE_LOC_BACKBOARD == GKT_DOOR_LOCK_LOCATION)
		case GKT_EVENT_SYSTEM:
			gkt_info("window_motor_torsion: <SYSTEM> (%u - %d)\n", id, (int)data);
			if ((GKT_WINDOW_SYSTEM_DOOR == minor_type)
				&& (GKT_DOOR_NOTIFY_LOCK_CONFIG == id)
				&& s_motor_torsion.update_setting) 
			{
				uint32_t result;

				result = (GKT_SUCCESS == data) ? 
					WINDOW_RESULT_SET_SUCCESS : WINDOW_RESULT_SET_FAILED;
				gkt_window_timer_clear(TIMER_ID_TIMEOUT);
				window_motor_torsion_complete(result);
			}
			break;
		case GKT_EVENT_TIMER:
			gkt_info("window_motor_torsion: TIMEOUT.\n");
			if ((TIMER_ID_TIMEOUT == minor_type)
				&& s_motor_torsion.update_setting)
			{
				window_motor_torsion_complete(WINDOW_RESULT_SET_FAILED);
			}
			break;
		case GKT_EVENT_VOICE:
			if (s_motor_torsion.play_over == 1) {
				s_motor_torsion.play_over = 0;
				gkt_window_exit();
			}
			break;
#endif
		default:
			break;
	}
	
	return retval;
}
GKT_WINDOW_DESC_DEFINE(motor_torsion);

#endif

